package com.itwk.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itwk.common.constant.PublishConstant;
import com.itwk.common.to.SkuBoundsTo;
import com.itwk.common.to.SkuReductionTo;
import com.itwk.common.to.StockTo;
import com.itwk.common.to.search.SearchModel;
import com.itwk.common.utils.PageUtils;
import com.itwk.common.utils.Query;
import com.itwk.common.utils.R;
import com.itwk.gulimall.product.dao.PmsSpuInfoDao;
import com.itwk.gulimall.product.entity.*;
import com.itwk.gulimall.product.feign.*;
import com.itwk.gulimall.product.service.*;
import com.itwk.gulimall.product.vo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("pmsSpuInfoService")
public class PmsSpuInfoServiceImpl extends ServiceImpl<PmsSpuInfoDao, PmsSpuInfoEntity> implements PmsSpuInfoService {
@Autowired
    private PmsSpuInfoDescService spuDecriptService; //产品介绍图服务，由于介绍图大且多单行记录
    @Autowired
    private PmsAttrService attrService;  //存储基本信息查询名字
    @Autowired
    private PmsProductAttrValueService productAttrValueService; //保存商品spu对应的基本属性信息
    @Autowired
    private PmsSkuSaleAttrValueService skuSaleAttrValueService;//保存sku关联的销售属性；
    @Autowired
    private PmsSkuImagesService skuImagesService;//保存根据商品sku选择的sku图
    @Autowired
    private PmsSkuInfoService  skuInfoService;  //保存sku信息
    @Autowired
    private PmsSpuImagesService spuImagesService;//保存spu 的所有图片
    @Autowired
    private SmsReductionFeign smsReductionFeign;  //远程调用优惠服务保存满减折扣
    @Autowired
    private SmsBoundsFeign smsBoundsFeign;  //保存用户积分信息
    @Autowired
    private SkuMenberPriceFeign menberPriceFeign;  //远程调用保存会员价格
    @Autowired
    private SkuLadderFeign ladderFeign ; //远程保存满几件打几折的折扣
    @Autowired
    private PmsBrandService brandService;  //查询品牌信息
    @Autowired
    private PmsCategoryService categoryService; //查询分类信息
    @Autowired
    private WareStockFeign wareStockFeign; //远程查询是否有库存
    @Autowired
    private SearchBulkFeign searchBulkFeign; //远程调用上架商品到ES

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        //status=2&key=..&brandId=3&catelogId=225&page=1&limit=10 取出检索条件

         String key  = (String) params.get("key"); //检索条件
         String brandId = (String) params.get("brandId"); //品牌id
         String catelogId = (String) params.get("catelogId"); //分类ID
         String status = (String) params.get("status"); //发布状态

        QueryWrapper<PmsSpuInfoEntity> wrapper = new QueryWrapper<>();
       //检索key
        if(!StringUtils.isEmpty(key)){
            wrapper.and(queryWarpper->{
                queryWarpper.eq("id", key).or().like("spu_name", key).or().like("spu_description", key);
            });
        }
         //检索品牌id
        if(!StringUtils.isEmpty(brandId)&&!"0".equals(brandId)){
            wrapper.eq("brand_id", brandId);


        }
        //检索分类
        if(!StringUtils.isEmpty(catelogId)&&!"0".equals(catelogId)){
            wrapper.eq("catalog_id", catelogId);
        }
      //检索状态
        if(!StringUtils.isEmpty(status)){
            wrapper.eq("publish_status", status);
        }

        IPage<PmsSpuInfoEntity> ipage = new Query<PmsSpuInfoEntity>().getPage(params);

        IPage<PmsSpuInfoEntity> page = baseMapper.selectPage(ipage, wrapper);

        return new PageUtils(page);
    }

    @Override
    @Transactional  //保存数据量较大，添加事物管理
    public void saveSpuVo(SaveSpuVo spuVo) {
        //保存spu的基本信息
        PmsSpuInfoEntity spuInfoEntity = new PmsSpuInfoEntity();
        BeanUtils.copyProperties(spuVo, spuInfoEntity); //spu表中的数据字段创建时间和修改时间没有对应，需要手动设置
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        baseMapper.insert(spuInfoEntity); //spu 信息保存
        //保存上商品介绍图
        List<String> decript = spuVo.getDecript();
        if(decript!=null&&decript.size()>0)
        spuDecriptService.saveSpuInfoDecript(spuInfoEntity.getId(),String.join(",",decript)); //将spu的介绍图保存，需要spuid ,String.join将集合内容以“，” 分割为字符串
       //保存商品的图集
        List<String> spuImages = spuVo.getImages();
        if(spuImages!=null && spuImages.size()>0){
            List<PmsSpuImagesEntity> collect = spuImages.stream().map(image -> {
                PmsSpuImagesEntity pmsSpuImagesEntity = new PmsSpuImagesEntity();
                pmsSpuImagesEntity.setImgUrl(image);
                pmsSpuImagesEntity.setSpuId(spuInfoEntity.getId());
                return pmsSpuImagesEntity;
            }).collect(Collectors.toList());

            spuImagesService.saveBatch(collect);
        }


        //保存商品spu基本属性信息
        List<BaseAttrs> baseAttrs = spuVo.getBaseAttrs();
        List<PmsProductAttrValueEntity> productAttrValueEntitys = baseAttrs.stream().map((attr) -> {
            PmsProductAttrValueEntity productAttrValueEntity = new PmsProductAttrValueEntity();
            productAttrValueEntity.setAttrId(attr.getAttrId());
            productAttrValueEntity.setAttrValue(attr.getAttrValues());
            productAttrValueEntity.setSpuId(spuInfoEntity.getId());
            productAttrValueEntity.setQuickShow(attr.getShowDesc()); //是否快速展示，0-不展示 ，1-展示
            PmsAttrEntity attrEntity = attrService.getById(attr.getAttrId());  //查询属性名
            productAttrValueEntity.setAttrName(attrEntity.getAttrName());

            return productAttrValueEntity;
        }).collect(Collectors.toList());

        productAttrValueService.saveBatch(productAttrValueEntitys);
       //保存sku信息
        List<Skus> skus = spuVo.getSkus();
        skus.forEach(sku->{
           /* private List<Attr> attr;    //销售属性，对应sku_sale_attr_value
            private String skuName;   //字段对应
            private BigDecimal price; //字段对应 价格
            private String skuTitle;   //字段对应 标题    前端对应字段
            private String skuSubtitle; //字段对应 副标题
            */
           //取出当前sku中图片的默认图片
            List<Images> skuImages= sku.getImages();
            String defaultImage="";
            if(skuImages!=null && skuImages.size()>0 ){
                for (Images skuImage : skuImages) {
                    if(skuImage.getDefaultImg()==1){
                        defaultImage=skuImage.getImgUrl();
                    }
                }
            }

           //设置sku的基本信息
            PmsSkuInfoEntity skuInfoEntity = new PmsSkuInfoEntity();
            BeanUtils.copyProperties(sku, skuInfoEntity);
            skuInfoEntity.setBrandId(spuVo.getBrandId());
            skuInfoEntity.setCatalogId(spuVo.getCatalogId());
            skuInfoEntity.setSaleCount(0L);
            skuInfoEntity.setSkuDefaultImg(defaultImage);
            skuInfoEntity.setSpuId(spuInfoEntity.getId());
            skuInfoService.save(skuInfoEntity);


            //把sku对应的销售属保存
            List<Attr> attrs = sku.getAttr();
            List<PmsSkuSaleAttrValueEntity> skuSaleAttrs = attrs.stream().map(attr -> {
                PmsSkuSaleAttrValueEntity pmsSkuSaleAttrValueEntity = new PmsSkuSaleAttrValueEntity();
                BeanUtils.copyProperties(attr, pmsSkuSaleAttrValueEntity);
                pmsSkuSaleAttrValueEntity.setSkuId(skuInfoEntity.getSkuId());
                return pmsSkuSaleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveBatch(skuSaleAttrs);
            List<Images> images = sku.getImages();
            if(images!=null&&images.size()>0){
                //选择保存商品sku图片
                List<PmsSkuImagesEntity> skuImages1 = images.stream().filter(image -> {
                    return image.getImgUrl() != null && image.getImgUrl().length() > 0;
                }).map(image -> {
                    PmsSkuImagesEntity imagesEntity = new PmsSkuImagesEntity();
                    BeanUtils.copyProperties(image, imagesEntity);
                    imagesEntity.setSkuId(skuInfoEntity.getSkuId());
                    return imagesEntity;
                }).collect(Collectors.toList());
                skuImagesService.saveBatch(skuImages1);
            }
            //保存满减优惠   保存满减优惠
            SkuReductionTo skuReductionTo = new SkuReductionTo();
            BeanUtils.copyProperties(sku, skuReductionTo);
            skuReductionTo.setSkuId(skuInfoEntity.getSkuId());
            //这里需要校验，如果没有设置折扣信息，此处保存值为0，没有意义则无需调用保存
            if(skuReductionTo.getFullPrice().compareTo(new BigDecimal(0))==1&& skuReductionTo.getReducePrice().compareTo(new BigDecimal(0))==1 ){
                R saveRedution = smsReductionFeign.save(skuReductionTo);
                if(saveRedution.getCode()!=0)
                    System.out.println("满减远程调用失败");
            }

            //保存买几件打几折,这里需要校验，如果没有设置折扣信息，此处保存值为0，没有意义则无需调用保存

            if(skuReductionTo.getFullCount()>0&&skuReductionTo.getDiscount().compareTo(new BigDecimal(0))==1){
                R saveLadder = ladderFeign.save(skuReductionTo);
                if(saveLadder.getCode()!=0)
                    System.out.println("买几件打几折保存远程调用失败");
            }

            //设置会员价格
            R saveMemberPrice = menberPriceFeign.save(skuReductionTo);
            if(saveMemberPrice.getCode()!=0)
                System.out.println("会员价格信息保存远程调用失败");

        });

        //金币成长值优惠微服务
        SkuBoundsTo skuBoundsTo = new SkuBoundsTo();
        Bounds bounds = spuVo.getBounds();
        BeanUtils.copyProperties(bounds, skuBoundsTo);
        skuBoundsTo.setSpuId(spuInfoEntity.getId());
        if(skuBoundsTo.getBuyBounds().compareTo(new BigDecimal(0))==1||skuBoundsTo.getGrowBounds().compareTo(new BigDecimal(0))==1){
            //成长值或者金币值有值再保存
            R saveBounds = smsBoundsFeign.save(skuBoundsTo);
            if(saveBounds.getCode()!=0)
                System.out.println("积分信息远程保存失败");

        }

    }

    @Override  //上架商品，保存数据模型
    public void spuUp(Long spuId) {
    //先查询数据模型中，相同数据部分避免 重复查询
        //查询出品牌和分类信息
        PmsSpuInfoEntity pmsSpuInfoEntity = baseMapper.selectById(spuId);
        Long brandId =pmsSpuInfoEntity.getBrandId();
        Long catalogId= pmsSpuInfoEntity.getCatalogId();
        PmsBrandEntity brandEntity = brandService.getById(brandId);
        PmsCategoryEntity categoryEntity = categoryService.getById(catalogId);
        String brandName=brandEntity.getName();
        String catalogName=categoryEntity.getName();
        //查询出属性信息
        List<PmsProductAttrValueEntity> attrValues = productAttrValueService.list(new QueryWrapper<PmsProductAttrValueEntity>().eq("spu_id", spuId)); //取得spu下全部属性

        //查询可被检索的属性
        List<PmsAttrEntity> attrEntities = attrService.list(new QueryWrapper<PmsAttrEntity>().eq("search_type", 1));
        //取出所有的ID
        List<Long> attrIds = attrEntities.stream().map(attr -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());
        //取出spu下可被检索的id
        List<PmsProductAttrValueEntity> attrValueIds = attrValues.stream().filter(attrValue -> {
            return attrIds.contains(attrValue.getAttrId());
        }).collect(Collectors.toList());
        //查询出可以被检索的属性
        List<PmsProductAttrValueEntity> entitys = productAttrValueService.list(new QueryWrapper<PmsProductAttrValueEntity>().in("attr_id",attrValueIds));
        List<SearchModel.Attrs> skuAttrs = entitys.stream().map(entiry -> {
            SearchModel.Attrs attrs = new SearchModel.Attrs();
            BeanUtils.copyProperties(entiry, attrs);
            return attrs;
        }).collect(Collectors.toList());

        //sku信息获取
        List<PmsSkuInfoEntity> skuInfoEntitys = skuInfoService.list(new QueryWrapper<PmsSkuInfoEntity>().eq("spu_id", spuId));

        //远程查询是否有库存
        List<Long> skuIds = skuInfoEntitys.stream().map(PmsSkuInfoEntity::getSkuId).collect(Collectors.toList());

        Map<Long, Boolean> stockMap =null;
        try{
            List<StockTo> stockTos = wareStockFeign.hasStock(skuIds);//查询所有的sku 对应的库存
            //拿到返回结果，遍历改为map
            if(stockTos!=null&&stockTos.size()>0){
                stockMap = stockTos.stream().collect(Collectors.toMap(StockTo::getSkuId, item -> item.getHasStock()));//将sku结果转为map
            }
            }catch (Exception e){
            log.error("远程查询库存出错{}"+e);
        }

        //遍历保存sku属性
        Map<Long, Boolean> finalStockMap = stockMap;
        List<SearchModel> seachModels = skuInfoEntitys.stream().map(skuInfo -> {
            SearchModel searchModel = new SearchModel();
            BeanUtils.copyProperties(skuInfo, searchModel);
            searchModel.setSkuImg(skuInfo.getSkuDefaultImg());
            searchModel.setSkuPrice(skuInfo.getPrice());
            searchModel.setBrandId(brandId);
            searchModel.setBrandName(brandName);
            searchModel.setCatalogId(catalogId);
            searchModel.setCatalogName(catalogName);
            searchModel.setAttrs(skuAttrs);
            //todo 远程调用查询库存
           if(finalStockMap !=null){ //不为空成空查询到库存
               searchModel.setHasStock(finalStockMap.get(skuInfo.getSkuId()));
           }else {
               //如果为空则远程调用异常，默认赋值有库存
               searchModel.setHasStock(true);
           }
            //todo 远程调用查询热度,暂且默认处理0
            searchModel.setHasScore(0L);
            return searchModel;

        }).collect(Collectors.toList());

         //远程调用feign 上架商品到es中
        R r = searchBulkFeign.saveProductEs(seachModels);
        if(r.getCode()==0){
            //todo 保存成功 去修改商品的发布状态
           baseMapper.updatePublish(spuId, PublishConstant.NEW_UP.getCode());
        }

    }

}